//
//  MessageCoreDataStorage.m
//  Gabber
//
//  Created by 陆惠国 on 11-9-29.
//  Copyright 2011年 恒生聚源. All rights reserved.
//

#import "MessageCoreDataStorage.h"
#import "XMPPCoreDataStorageProtected.h"
#import "Message.h"

@implementation MessageCoreDataStorage

static MessageCoreDataStorage *sharedInstance;

+ (MessageCoreDataStorage *)sharedInstance
{
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		
		sharedInstance = [[MessageCoreDataStorage alloc] initWithDatabaseFilename:nil];
	});
	
	return sharedInstance;
}

#pragma - mark Setup

- (id)init
{
	return [self initWithDatabaseFilename:nil];
}

- (id)initWithDatabaseFilename:(NSString *)aDatabaseFileName
{
	if ((self = [super initWithDatabaseFilename:aDatabaseFileName]))
	{
	}
	return self;
}

- (BOOL)configureWithParent:(MessageModule *)aParent queue:(dispatch_queue_t)queue
{
	return [super configureWithParent:aParent queue:queue];
}


#pragma - mark Private

- (void)_clearAllMessagesForXMPPStream:(XMPPStream *)stream
{
	NSManagedObjectContext *moc = [self managedObjectContext];
	
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message"
	                                          inManagedObjectContext:moc];
	
	NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
	[fetchRequest setEntity:entity];
	[fetchRequest setFetchBatchSize:saveThreshold];
	
	if (stream)
	{
		NSPredicate *predicate;
		predicate = [NSPredicate predicateWithFormat:@"streamBareJidStr == %@",
                     [[self myJIDForXMPPStream:stream] bare]];
		
		[fetchRequest setPredicate:predicate];
	}
	
	NSArray *allMessages = [moc executeFetchRequest:fetchRequest error:nil];
	
	NSUInteger unsavedCount = [self numberOfUnsavedChanges];
	
	for (Message *message in allMessages)
	{
		[moc deleteObject:message];
		
		if (++unsavedCount >= saveThreshold)
		{
			[self save];
		}
	}
}

- (void)_clearMessagesForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
	NSManagedObjectContext *moc = [self managedObjectContext];
	
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message"
	                                          inManagedObjectContext:moc];
	
	NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
	[fetchRequest setEntity:entity];
	[fetchRequest setFetchBatchSize:saveThreshold];
	
	if (stream)
	{
		NSPredicate *predicate;
		predicate = [NSPredicate predicateWithFormat:@"streamBareJidStr == %@ AND jidStr == %@",
                     [[self myJIDForXMPPStream:stream] bare], [jid bare]];
		
		[fetchRequest setPredicate:predicate];
	}
	
	NSArray *allMessages = [moc executeFetchRequest:fetchRequest error:nil];
	
	NSUInteger unsavedCount = [self numberOfUnsavedChanges];
	
	for (Message *message in allMessages)
	{
		[moc deleteObject:message];
		
		if (++unsavedCount >= saveThreshold)
		{
			[self save];
		}
	}
    
}

- (void)_clearAllReadedMessagesForXMPPStream:(XMPPStream *)stream
{
	NSManagedObjectContext *moc = [self managedObjectContext];
	
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message"
	                                          inManagedObjectContext:moc];
	
	NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
	[fetchRequest setEntity:entity];
	[fetchRequest setFetchBatchSize:saveThreshold];
	
	if (stream)
	{
		NSPredicate *predicate;
		predicate = [NSPredicate predicateWithFormat:@"streamBareJidStr == %@ AND read == %@",
                     [[self myJIDForXMPPStream:stream] bare], [NSNumber numberWithBool:YES]];
		
		[fetchRequest setPredicate:predicate];
	}
	
	NSArray *allMessages = [moc executeFetchRequest:fetchRequest error:nil];
	
	NSUInteger unsavedCount = [self numberOfUnsavedChanges];
	
	for (Message *message in allMessages)
	{
		[moc deleteObject:message];
		
		if (++unsavedCount >= saveThreshold)
		{
			[self save];
		}
	}
}

- (void)_clearReadedMessagesForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
	NSManagedObjectContext *moc = [self managedObjectContext];
	
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message"
	                                          inManagedObjectContext:moc];
	
	NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
	[fetchRequest setEntity:entity];
	[fetchRequest setFetchBatchSize:saveThreshold];
	
	if (stream)
	{
		NSPredicate *predicate;
		predicate = [NSPredicate predicateWithFormat:@"streamBareJidStr == %@ AND jidStr == %@ AND read == %@",
                     [[self myJIDForXMPPStream:stream] bare], [jid bare], [NSNumber numberWithBool:YES]];
		
		[fetchRequest setPredicate:predicate];
	}
	
	NSArray *allMessages = [moc executeFetchRequest:fetchRequest error:nil];
	
	NSUInteger unsavedCount = [self numberOfUnsavedChanges];
	
	for (Message *message in allMessages)
	{
		[moc deleteObject:message];
		
		if (++unsavedCount >= saveThreshold)
		{
			[self save];
		}
	}
    
}

#pragma - mark MessageStorage
- (void)clearAllMessagesForXMPPStream:(XMPPStream *)stream
{
    [self scheduleBlock:^{
		[self _clearAllMessagesForXMPPStream:stream];
	}];
}
- (void)clearMessagesForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
    [self scheduleBlock:^{
		[self _clearMessagesForJID:jid xmppStream:stream];
	}];
    
}

- (void)clearAllReadedMessagesForXMPPStream:(XMPPStream *)stream
{
    [self scheduleBlock:^{
		[self _clearAllReadedMessagesForXMPPStream:stream];
	}];
}
- (void)clearReadedMessagesForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
    [self scheduleBlock:^{
		[self _clearReadedMessagesForJID:jid xmppStream:stream];
	}];
    
}


- (void)handleMessage:(XMPPMessage *)message xmppStream:(XMPPStream *)stream
{
 
	[self scheduleBlock:^{
		
		NSManagedObjectContext *moc = [self managedObjectContext];
        NSString *streamBareJidStr = [[self myJIDForXMPPStream:stream] bare];
        
        [Message insertInManagedObjectContext:moc withMessage:message streamBareJidStr:streamBareJidStr];

	}];
}


- (void)readMessage:(Message *)message
{
 	[self scheduleBlock:^{
		
        [message setHasBeenRead:YES];
        [self save];
        
	}];   
}


@end
